package com.ex.net;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.net.http.AndroidHttpClient;

import com.ex.util.LogUtil;
import com.example.androiddemo.Const;

public class HttpRequestUtils {
	
	/**
	 * HttpUrlConnection 方式连接请求
	 * @param url_path
	 * @return
	 */
	public static String httpReq(String url_path) {
		try {
			URL url = new URL(url_path);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(3000);
			connection.setRequestMethod("POST");
			connection.setDoInput(true);
			connection.setDoOutput(true);
			int code = connection.getResponseCode();
			if(code == 200) {
				return changeInputStream(connection.getInputStream());
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static String javaNetPostParam(String urlPath) {
		String result = "";
		try {
			URL url = new URL(urlPath);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			connection.setConnectTimeout(6 * 1000);
			connection.setDoInput(true);
			connection.setDoOutput(true);
			DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
			String params = "userName=thduan&age=12";
			outputStream.writeBytes(params);
			outputStream.flush();
			outputStream.close();
			
			int resCode = connection.getResponseCode();
			if(resCode == 200) {
				result = changeInputStream(connection.getInputStream());
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		return result;
	}
	
	public static String androidHttpClientReq(final String uri) {
		String result = "";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("userName", "thduan"));
		params.add(new BasicNameValuePair("age", String.valueOf(18)));
		try {
			HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
			HttpPost httpPost = new HttpPost(uri);
			httpPost.setEntity(entity);
			AndroidHttpClient httpClient = AndroidHttpClient.newInstance("");
			HttpResponse response = httpClient.execute(httpPost);
			if(response.getStatusLine().getStatusCode() == 200) {
				//EntityUtils 提供了处理 HttpEntity的static方法， 
				//toString ： 将httpEntity的数据从inputStream中读取出来，转换成string
				result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
			}else {
				result = "请求失败";
			}
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public static String httpClientReq(final String uri) {
		String result = "";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("userName", "thduan"));
		params.add(new BasicNameValuePair("age", String.valueOf(18)));
		try {
			HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
			HttpPost httpPost = new HttpPost(uri);
			httpPost.setEntity(entity);
			DefaultHttpClient client = new DefaultHttpClient();
			HttpResponse response = client.execute(httpPost);
			if(response.getStatusLine().getStatusCode() == 200) {
				//EntityUtils 提供了处理 HttpEntity的static方法， 
				//toString ： 将httpEntity的数据从inputStream中读取出来，转换成string
				result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
			}else {
				result = "请求失败";
			}
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	private static String changeInputStream(InputStream stream) {
		String result = "";
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		int length = 0;
		byte[] data = new byte[1024];
		try {
			while ((length = stream.read(data)) != -1) {
				outputStream.write(data, 0, length);
			}
			result = new String(outputStream.toByteArray());
		} catch (Exception e) {
		}
		
		
		return result;
	}
	
	/**
	 * 使用 DefaultHttpClient上传文件，注意：httpClient4.5 会报错， 有些方法、字段找不到；
	 * 改用4.2版本，客户端运行正常，但 服务器端报错，Processing of multipart/form-data request failed. Stream ended unexpectedly
	 * 最终没搞成功，可能是版本不对吧， httpClient 部分android自带了，加入包之后可能有些问题
	 * 
	 * 转向HttpUrlConnection @see httpUrlConnUpload(String url) method
	 * 
	 * @param url
	 * @return
	 */
	public static String uploadFile(String url) {
		String result = "";
		HttpPost httpPost = new HttpPost(url);
		FileBody f1 = new FileBody(new File(Const.SDCARD_PATH + "up" + File.separator + "fileMaomao.txt"));
		FileBody f2 = new FileBody(new File(Const.SDCARD_PATH + "up" + File.separator + "fileEyu.txt"));
		StringBody commonBody = null;
		try {
			commonBody = new StringBody("common str");
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		MultipartEntity reqEntity = new MultipartEntity();
		reqEntity.addPart("fileMao", f1);
		reqEntity.addPart("fileEyu", f2);
		reqEntity.addPart("commonStr", commonBody);
		httpPost.setEntity(reqEntity);
		
//		 HttpEntity reqEntity = MultipartEntityBuilder.create()
//				 				.addPart(f1.getFilename(), f1)
//				 				.addPart(f2.getFilename(), f2)
////				 				.addPart("commonBody", commonBody)
//				 				.build();
		 httpPost.setEntity(reqEntity);
		
//		DefaultHttpClient client = new DefaultHttpClient();
////	    HttpClient client = AndroidHttpClient.newInstance("");
//	    //不设置超时时间的话， 请求完了就立即关闭连接了，服务器端还没接收完[正在读取]遇到客户端关闭了会发生异常
//		client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 6 * 10000);
//		client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 6 * 10000);
		DefaultHttpClient client = getHttpClient();
		
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			int resCode = response.getStatusLine().getStatusCode();
			if(resCode == HttpStatus.SC_OK) {
				HttpEntity resEntity = response.getEntity();
				result = EntityUtils.toString(resEntity);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	private static DefaultHttpClient getHttpClient() {
		final int CONNECT_TIMEOUT = 30 * 1000;
		HttpParams httpParams = new BasicHttpParams();
		//设置最大连接数
		ConnManagerParams.setMaxTotalConnections(httpParams, 800);
		//设置连接超时时间
		ConnManagerParams.setTimeout(httpParams, CONNECT_TIMEOUT);
		ConnPerRouteBean connPerRouteBean = new ConnPerRouteBean(400);
		ConnManagerParams.setMaxConnectionsPerRoute(httpParams, connPerRouteBean);
		
		//设置连接超时时间
		HttpConnectionParams.setConnectionTimeout(httpParams, CONNECT_TIMEOUT);
		//设置读取超时时间
		HttpConnectionParams.setSoTimeout(httpParams, CONNECT_TIMEOUT);
		
		DefaultHttpClient client = new DefaultHttpClient(httpParams);
		client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECT_TIMEOUT);
		client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, CONNECT_TIMEOUT);
		return client;
	}
	
	public static String httpUrlConnUpload(String URI_PATH) {
		String result = "";
		String BOUNDARY = java.util.UUID.randomUUID().toString();  
        String PREFIX = "--", LINEND = "\r\n";  
        String MULTIPART_FROM_DATA = "multipart/form-data";  
        String CHARSET = "UTF-8";  
        
        URL uri;
        
        long start = System.currentTimeMillis();
        
		try {
			uri = new URL(URI_PATH);
			Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Const.HTTP_PROXY_ADDRESS, Const.HTTP_PROXY_PORT));
			HttpURLConnection conn = (HttpURLConnection) uri.openConnection();  
			//使用内网代理
//			HttpURLConnection conn = (HttpURLConnection) uri.openConnection(proxy);
			//相关设置
	        conn.setReadTimeout(5 * 1000); // 缓存的最长时间  
	        conn.setDoInput(true);// 允许输入  
	        conn.setDoOutput(true);// 允许输出  
	        conn.setUseCaches(false); // 不允许使用缓存  
	        conn.setRequestMethod("POST");  
	        conn.setRequestProperty("connection", "keep-alive");  
	        conn.setRequestProperty("Charsert", "UTF-8");  
	        conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA  
	                + ";boundary=" + BOUNDARY); 
	        
	        //HttpUrlConnection 输出流，向服务端写数据
	        DataOutputStream outStream = new DataOutputStream(  
	                conn.getOutputStream());  
	        
	        InputStream in = null;  
	        //写文件字段头
	        StringBuilder sb1 = new StringBuilder();  
            sb1.append(PREFIX);  
            sb1.append(BOUNDARY);  
            sb1.append(LINEND);  
            sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"fileThduan"  
                     + "\"" + LINEND);  
            sb1.append("Content-Type: application/octet-stream; charset="  
                    + CHARSET + LINEND);  
            sb1.append(LINEND);  
            outStream.write(sb1.toString().getBytes());  
            
            //写文件内容
            File file = new File(Const.SDCARD_PATH + "/up" + File.separator + "fileEyu.txt");
            InputStream is = new FileInputStream(file);  
            byte[] buffer = new byte[1024];  
            int len = 0;  
            while ((len = is.read(buffer)) != -1) {  
                outStream.write(buffer, 0, len);  
            }  

            is.close();  
            outStream.write(LINEND.getBytes());
            
            //普通参数
            StringBuilder normalParam = new StringBuilder();
            normalParam.append(PREFIX + BOUNDARY + LINEND);
            normalParam.append("Content-Disposition: form-data;name=\"type\"" + LINEND + LINEND);
            normalParam.append(URLEncoder.encode("avatar", "UTF-8"));
            normalParam.append(LINEND + LINEND);
            //普通参数值
            outStream.writeBytes(normalParam.toString());
            
            // 请求结束标志  
	        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();  
	        outStream.write(end_data);  
	        outStream.flush();  
	        
	        // 得到响应码  
	        int res = conn.getResponseCode();  
	        if (res == 200) {  
	            in = conn.getInputStream();  
	            int ch;  
	            StringBuilder sb2 = new StringBuilder();  
	            while ((ch = in.read()) != -1) {  
	                sb2.append((char) ch);  
	            }  
	            result = sb2.toString();
	        }  
	        outStream.close();  
	        conn.disconnect(); 
	        
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
		e.printStackTrace();
		}  
        long end = System.currentTimeMillis();
        long costTime = end - start;
        LogUtil.log("上传时间：" + costTime + " 毫秒");
        return result;
		
	}
	
	public static void downloadFileHttpUrlConn(String urlP) {
		try {
			URL url = new URL(urlP);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}
